// #pragma once
// #include <semaphore.h>
// #include <vector>

// template <typename T>
// class RingQueue
// {
// public:
//     RingQueue(unsigned int capacity)
//         :_capacity(capacity)
//         , _size(0)
//     {
//         _queue.resize(_capacity);
//         sem_init(&_fmutex, 0, 1); // 队头互斥量
//         sem_init(&_rmutex, 0, 1); // 队尾互斥量
//         sem_init(&_empty, 0, _capacity);
//         sem_init(&_full, 0, 0);
//     }
//     ~RingQueue()
//     {
//         sem_destroy(&_fmutex);
//         sem_destroy(&_rmutex);
//         sem_destroy(&_empty);
//         sem_destroy(&_full);
//     }

//     void push(const T& data)
//     {
//         sem_wait(&_empty);
//         sem_wait(&_rmutex);
//         _queue[_rear] = data;
//         _rear = (_rear + 1) % _capacity;
//         sem_post(&_rmutex);
//         sem_post(&_full);
//     }
//     T pop()
//     {
//         sem_wait(&_full);
//         sem_wait(&_fmutex);
//         T ret = _queue[_front];
//         _front = (_front + 1) % _capacity;
//         sem_post(&_fmutex);
//         sem_post(&_empty);
//         return ret;
//     }

//     unsigned int size()
//     {
//         return _size;
//     }
//     unsigned int capacity()
//     {
//         return _capacity;
//     }
//     bool empty()
//     {
//         return _size == 0;
//     }
// private:
//     std::vector<int> _queue;
//     unsigned int _capacity, _size; // 容量, 大小
//     unsigned int _front; // 队头指针
//     unsigned int _rear; // 队尾指针
//     sem_t _fmutex, _rmutex, _empty, _full;
// };

#pragma once
#include <semaphore.h>
#include <vector>
#include "Sem.hpp"

template <typename T>
class RingQueue
{
public:
    RingQueue(unsigned int capacity)
        :_queue(capacity)
        , _capacity(capacity)
        , _size(0)
        , _fmutex(1)
        , _rmutex(1)
        , _empty(capacity)
        , _full(0)
    {}
    ~RingQueue()
    {}

    void push(const T& data)
    {
        _empty.wait();
        _rmutex.wait();
        _queue[_rear] = data;
        _rear = (_rear + 1) % _capacity;
        _rmutex.post();
        _full.post();
    }
    T pop()
    {
        _full.wait();
        _fmutex.wait();
        T ret = _queue[_front];
        _front = (_front + 1) % _capacity;
        _fmutex.post();
        _empty.post();
        return ret;
    }

private:
    std::vector<int> _queue;
    unsigned int _capacity; // 容量
    unsigned int _front; // 队头指针
    unsigned int _rear; // 队尾指针
    SemModule::Sem _fmutex, _rmutex, _empty, _full;
};